package org.grc.app.z_project.z_framework.helper;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import org.grc.app.z_project.z_framework.ConfigHelper;
import org.grc.app.z_project.z_framework.annotation.Controller;
import org.grc.app.z_project.z_framework.annotation.Service;
import org.grc.app.z_project.z_framework.util.ClassUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 类操作助手类
 * 
 * @author grc
 * @since 1.0-SNAPSHOT
 */
public final class ClassHelper {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ClassHelper.class);

	/**
	 * 定义类集合（用于存放所有加载类）
	 */
	private static final Set<Class<?>> CLASS_SET;
	
	// 加载主包下的所有类
	static {
		String basePackage = ConfigHelper.getAppBasePackage();
		CLASS_SET = ClassUtil.getClassSet(basePackage);
	}
	
	/**
	 * 获取应用包名下的所有类
	 */
	public static Set<Class<?>> getClassSet () {
		return CLASS_SET;
	}
	
	/**
	 * 获取应用包名下的所有Service类
	 */
	public static Set<Class<?>> getServiceClassSet () {
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for (Class<?> clazz : CLASS_SET) {
			if (clazz.isAnnotationPresent(Service.class)) {
				classSet.add(clazz);
			}
		}
		return classSet;
	}
	
	/**
	 * 获取应用包名下的所有Controller类
	 */
	public static Set<Class<?>> getControllerClassSet () {
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for (Class<?> clazz : CLASS_SET) {
			if (clazz.isAnnotationPresent(Controller.class)) {
				classSet.add(clazz);
			}
		}
		return classSet;
	}
	
	/**
	 * 获取应用报名下的所有Bean类（包括Service 和 Controller）
	 */
	public static Set<Class<?>> getBeanClassSet () {
		Set<Class<?>> beanClassSet = new HashSet<Class<?>>();
		beanClassSet.addAll(getServiceClassSet());
		beanClassSet.addAll(getControllerClassSet());
		return beanClassSet;
	}
	
	/**
	 * 根据传入的接口类返回对应的实现类 <b>注：如果有多个实现类也只返回其中最后的一个</b>。
	 */
	public static Class<?> getImplClassByInterfaceClass (Class<?> interfaceClass) {
		Class<?> implClazz = null;
		if (interfaceClass.isInterface()) {
			for (Class<?> cls : CLASS_SET) {
				if (interfaceClass.isAssignableFrom(cls)) {
					implClazz = cls;
				}
			}
		} else {
			// 返回null
		}
		return implClazz;
	}
	
	/**
	 * 获取应用包名下某父类（或接口）的所有子类（或实现类）
	 */
	public static Set<Class<?>> getClassSetBySuper (Class<?> superClass) {
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for (Class<?> clazz : CLASS_SET) {
			if (superClass.isAssignableFrom(clazz) && !superClass.equals(clazz)) {
				classSet.add(clazz);
			}
		}
		return classSet;
	}
	
	/**
	 * 获取应用包名下带有某注解的所有类
	 */
	public static Set<Class<?>> getClassSetByAnnotation (Class<? extends Annotation> annotationClass) {
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for (Class<?> clazz : CLASS_SET) {
			if (clazz.isAnnotationPresent(annotationClass)) {
				classSet.add(clazz);
			}
		}
		return classSet;
	}
}
